package com.flyox.game.fivetiger.model;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Observable;
import java.util.Stack;

import com.flyox.game.fivetiger.bean.CONSTS;
import com.flyox.game.fivetiger.bean.ChessOptions;
import com.flyox.game.fivetiger.bean.MsgPackage;
import com.flyox.game.fivetiger.bean.Position;
import com.flyox.game.fivetiger.tools.UtilBean;

public class Document extends Observable implements Serializable {

	private static final long serialVersionUID = -8571151370804684032L;

	private int layout[][] = new int[5][5];
	private String name = "";// three:client or zero:server
	private int currentState = CONSTS.CMD_BEGIN;// 当前状态
	private String currentPlayer = CONSTS.SYS_SERVER_NAME;// 当前操作方
	private int canRemoveChessCount = 0;// 剩余拔棋或者压棋数量
	private boolean otherSideNeedCut = false;// 无棋可走才能相互拔掉对方一个棋子
	private String stateMsg = "";// 当前状态信息

	private Stack stepts = new Stack();
	private transient ChessOptions chessOptions = new ChessOptions();

	/**
	 * ChessOptions--》不重新初始化
	 */
	public void reInit() {
		setLayout(new int[5][5]);
		setCurrentState(CONSTS.CMD_BEGIN);
		setCurrentPlayer(CONSTS.SYS_SERVER_NAME);
		setCanRemoveChessCount(0);
		setOtherSideNeedCut(false);
		//saveStepts("c:/Temp/data.fcs");
		stepts.clear();
	}

	/**
	 * 保存过程
	 * @param path
	 */
	public void saveStepts(String path){
		if (!stepts.isEmpty()) {
			try {
				ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(path));
				oos.writeObject(stepts);
				oos.close();
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	public int getCurrentState() {
		return currentState;
	}

	public void setCurrentState(int currentState) {
		this.currentState = currentState;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_STATE);
	}

	public String getCurrentPlayer() {
		return currentPlayer;
	}

	public void setCurrentPlayer(String currentPlayer) {
		this.currentPlayer = currentPlayer;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_CURRENT_PLAYER);
	}

	public int[][] getLayout() {
		return layout;
	}

	public void setLayout(int[][] layout) {
		this.layout = layout;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
	}

	public void setLayout(Position pos, int flag) {
		layout[pos.row][pos.col] = flag;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
	}

	/**
	 * 判断是否填满 如果填满进入第二阶段
	 * 
	 * @return
	 */
	public boolean isFull() {
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (layout[i][j] == CONSTS.CHESS_EMPTY) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 判断输赢 1 2
	 */
	public boolean isOver(int team) {
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (layout[i][j] == team) {
					return false;
				}
			}
		}
		return true;
	}

	/**
	 * 判断是否是当前用户 走棋
	 * 
	 * @return
	 */
	public boolean isCurrentPlayerPlay() {
		if (name.equals(currentPlayer)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 添加棋子
	 * 
	 * @param pos
	 */
	public int addCurrenPlayerChess(Position pos) {
		if (name.equals(CONSTS.SYS_SERVER_NAME)) {
			layout[pos.row][pos.col] = CONSTS.CHESS_ZERO;
		} else {
			layout[pos.row][pos.col] = CONSTS.CHESS_THREE;
		}
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
		// is shape 返回可以拔掉棋子的个数
		return new UtilBean().checkShapeRemove(layout, pos);
	}

	/**
	 * 添加对方棋子
	 * 
	 * @param pos
	 */
	public int addOtherSidePlayerChess(Position pos) {
		if (name.equals(CONSTS.SYS_SERVER_NAME)) {
			layout[pos.row][pos.col] = CONSTS.CHESS_THREE;
		} else {
			layout[pos.row][pos.col] = CONSTS.CHESS_ZERO;
		}
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
		return 0;
	}

	/**
	 * 得到对方的名字
	 * 
	 * @return
	 */
	public String getOtherSideName() {
		if (name.equals(CONSTS.SYS_SERVER_NAME)) {
			return CONSTS.SYS_CLIENT_NAME;
		} else {
			return CONSTS.SYS_SERVER_NAME;
		}
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_PLAYER);
	}

	/**
	 * 得到棋子标志 1 or 2
	 * 
	 * @return
	 */
	public int getTeamFlag() {
		if (name.equals(CONSTS.SYS_SERVER_NAME)) {
			return CONSTS.CHESS_ZERO;
		} else {
			return CONSTS.CHESS_THREE;
		}
	}

	/**
	 * 得到对法棋子标志 1 or 2
	 * 
	 * @return
	 */
	public int getOtherSideTeamFlag() {
		if (name.equals(CONSTS.SYS_SERVER_NAME)) {
			return CONSTS.CHESS_THREE;
		} else {
			return CONSTS.CHESS_ZERO;
		}
	}

	/**
	 * 设置为被覆盖 1 to 4 2 to 3
	 * 
	 * @param pos
	 */
	public void setOnCover(Position pos) {
		if (layout[pos.row][pos.col] == CONSTS.CHESS_ZERO) {
			layout[pos.row][pos.col] = CONSTS.CHESS_THREE_ZERO;
		} else if (layout[pos.row][pos.col] == CONSTS.CHESS_THREE) {
			layout[pos.row][pos.col] = CONSTS.CHESS_ZERO_THREE;
		}
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
	}

	/**
	 * 设置为被覆盖 1 to 4 2 to 3
	 * 
	 * @param pos
	 */
	public void unDoOnCover(Position pos) {
		if (layout[pos.row][pos.col] == CONSTS.CHESS_THREE_ZERO) {
			layout[pos.row][pos.col] = CONSTS.CHESS_ZERO;
		} else if (layout[pos.row][pos.col] == CONSTS.CHESS_ZERO_THREE) {
			layout[pos.row][pos.col] = CONSTS.CHESS_THREE;
		}
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
	}

	/**
	 * 清楚所有被覆盖棋子
	 */
	public void removeAllCovered() {
		if (!isFull()) {// 没有下瞒不能清除
			return;
		}

		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				if (layout[i][j] == CONSTS.CHESS_THREE_ZERO || layout[i][j] == CONSTS.CHESS_ZERO_THREE) {
					layout[i][j] = CONSTS.CHESS_EMPTY;
				}
			}
		}
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
	}

	/**
	 * 走棋 check 当前用户，用户状态，from 自己的棋子，to empty
	 * 
	 * @param from
	 * @param to
	 * @return
	 */
	public int move(Position from, Position to) {
		layout[to.row][to.col] = layout[from.row][from.col];
		layout[from.row][from.col] = CONSTS.CHESS_EMPTY;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
		// 检查是否成型 并返回可以拔掉棋子的个数
		return new UtilBean().checkShapeRemove(layout, to);
	}

	public boolean cutChess(Position pos) {
		layout[pos.row][pos.col] = CONSTS.CHESS_EMPTY;
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_LAYOUT);
		return true;
	}

	public int getCanRemoveChessCount() {
		return canRemoveChessCount;
	}

	public void setCanRemoveChessCount(int canRemoveChessCount) {
		this.canRemoveChessCount = canRemoveChessCount;
	}

	public boolean isOtherSideNeedCut() {
		return otherSideNeedCut;
	}

	public void setOtherSideNeedCut(boolean otherSideNeedCut) {
		this.otherSideNeedCut = otherSideNeedCut;
	}

	public void showLayout() {
		System.out.println(name);
		for (int i = 0; i < 5; i++) {
			for (int j = 0; j < 5; j++) {
				System.out.print(layout[i][j] + " ");
			}
			System.out.println();
		}
	}

	public void pushStept(MsgPackage packet) {
		stepts.push(packet);
	}

	public MsgPackage popStept() {
		return (MsgPackage) stepts.pop();
	}

	public MsgPackage peepStept() {
		return (MsgPackage) stepts.peek();
	}

	public boolean isSteptsNull() {
		if (stepts.isEmpty()) {
			return true;
		} else {
			return false;
		}
	}

	public void showStept() {
		System.out.println(this.getName());
		int size = stepts.size();
		for (int i = 0; i < size; i++) {
			MsgPackage mp = (MsgPackage) stepts.elementAt(i);
			System.out.println("" + i + " " + mp.toString());
		}
	}

	public String getStateMsg() {
		return stateMsg;
	}

	public void setStateMsg(String stateMsg) {
		if (stateMsg != null && stateMsg.length() > 20) {
			this.stateMsg = stateMsg.substring(0, 20);
		} else {
			this.stateMsg = stateMsg;
		}
		this.setChanged();
		notifyObservers(CONSTS.FLAG_CHANGE_STATE_MSG);
	}

	public ChessOptions getChessOptions() {
		return chessOptions;
	}

	public void setChessOptions(ChessOptions chessOptions) {
		this.chessOptions = (ChessOptions) chessOptions.clone();
	}
}
